home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 13316 / 13316.xpi / content / treeViewChanger.js < prev    next >
Text File  |  2009-07-25  |  15KB  |  470 lines

  1.  
  2. /* Copyright (C) 2009 Norman Solomon
  3.  * e-mail: historytree.addon@yahoo.com
  4.  * 
  5.  * The contents of this file are subject to the Mozilla Public License Version
  6.  * 1.1 (the "License"); you may not use this file except in compliance with
  7.  * the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
  8.  *
  9.  * Software distributed under the License is distributed on an "AS IS" basis,
  10.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11.  * for the specific language governing rights and limitations under the License.
  12.  */
  13.  
  14. // ****************************************************************************
  15. // *****                                                                  *****
  16. // *****    TREE-VIEW FUNCTIONS THAT RESPOND TO AND PROCESS GUI EVENTS    *****
  17. // *****    ----------------------------------------------------------    *****
  18. // *****      1) Process user's mouse-clicks on TreeView gCanvas          *****
  19. // *****      2) Sets gTreeNode[] pointers for TreeView quick-views       *****
  20. // *****                                                                  *****
  21. // ****************************************************************************
  22.  
  23. // ==========================================================================
  24. // Called from canvasMouseClickEventHandler() in "historyViewer.js" - which
  25. // is in turn called from "historyViewer.xul" <html:canvas ...> onclick()
  26. // --------------------------------------------------------------------------
  27. // Does req process when the user clicks on a TreeNode box on the gCanvas
  28. // ==========================================================================
  29. function respondToTreeViewMouseClickOnCanvas(x, y)
  30. {
  31.     // Get mouse click event info in Point(x,y) form
  32.     // x = button click constant; y = index of TreeNode in gTreeNodes[]
  33.     var clickResult = treeViewButtonFromMouseClick(x, y);
  34.  
  35.     // Get the button and TreeNode that the user clicked on
  36.     var btnClicked = clickResult.x;
  37.     var node = gTreeNodes[clickResult.y];
  38.  
  39.     // -----------------------------------------------------------
  40.     // If an expanded image is currently visible clear it, then...
  41.     if (gExpandedNode !== null)
  42.     {
  43.         // Exit if user clicks on SAME "?" button twice in succesion
  44.         if (btnClicked === BTN_SHOW_IMAGE && node === gExpandedNode)        
  45.         {
  46.             drawTree(false, null, null);
  47.             return;
  48.         }
  49.  
  50.         // Clear expanded image (sets gExpandedNode = null)
  51.         drawTree(false, null, null);
  52.  
  53.         // Exit if user clicked on the image or root info box, because
  54.         // clicks on buttons or nodes hidden BEHIND these are confusing
  55.         if (x > gImgXY.x && x < gImgXY.x + gInfoBoxWH.x 
  56.          && y > gImgXY.y && y < gImgXY.y + gInfoBoxWH.y)
  57.         {
  58.             return;
  59.         }
  60.     }
  61.  
  62.     // -------------------------------------------------------------
  63.     // Do req process if user clicked on drawn node box or button
  64.     if (btnClicked === BTN_CHANGE_TREE)
  65.     {
  66.         // Expand or contract sub-tree
  67.         showOrHideSubTreeForRoot(node);
  68.     }
  69.     else if (btnClicked === BTN_SHOW_IMAGE)
  70.     {
  71.         // Reset global flags that control image expansion
  72.         gExpandedNode = node;
  73.         
  74.         // Expand node image or draw root node info box
  75.         // *** ASSUMES that tree root node is in gTreeNodes[0]
  76.         if (clickResult.y === 0)
  77.         {
  78.             gNodeImageWid = 0;        
  79.             drawSessInfoBox(node);
  80.         }
  81.         else
  82.         {
  83.             // Start setInterval() that produces image expansion *** NOTE
  84.             // Some PC's have slow graphics - So uses 10 steps of 75 to 750
  85.             gNodeImageWid = 75;
  86.             gImgExpandInterval = setInterval
  87.                 (drawExpandingNodeImageOnCanvas, 18, node);
  88.         }
  89.     }
  90.     else if (btnClicked === BTN_OPEN_PAGE)
  91.     {        
  92.         // Open page in FF if user clicked on a TreeNode
  93.         // "Dummy" Tree root in gTreeNodes[0] is ignored
  94.         if (clickResult.y !== 0)
  95.             openOrGotoSelectedHistoryPage(node);
  96.     }
  97. }
  98.  
  99. // ============================================================================
  100. // Called from respondToTreeViewMouseClickOnCanvas - Returns Point(x,y) where;
  101. // ----------------------------------------------------------------------------
  102. // x = Integer for button clicked (see global constants in "historyViewer.js")
  103. // y = The index in gTreeNodes[] of the TreeNode that the user clicked on
  104. // ============================================================================
  105. function treeViewButtonFromMouseClick(x, y)
  106. {
  107.     var node;
  108.     var halfBtnHgt = BOX_BTN_HGT / 2;
  109.     
  110.     // ---------------------------------------------------------------
  111.     // Loop down gTreeNodes and find node clicked on (if any)
  112.     // *** NOTE - The nested if() structure and added TreeNode props
  113.     // are built for accurate, but above all, FAST click detection
  114.     // ---------------------------------------------------------------
  115.     for (var i = 0; i < gTreeNodes.length; i++)
  116.     {
  117.         // Get the TreeNode from gTreeNodes[]
  118.         node = gTreeNodes[i];
  119.  
  120.         // Ignore hidden nodes
  121.         if (!node.hidden)
  122.         {
  123.             // Check if user clicked anywhere on the overall node box
  124.             if (x > node.pos.x 
  125.              && x < node.pos.x + node.width
  126.              && y > node.pos.y 
  127.              && y < node.pos.y + node.height + halfBtnHgt)
  128.             {
  129.                 // Check if user clicked on button panel at bottom of box
  130.                 if (x > node.btnPanelX 
  131.                  && x < node.btnPanelX + node.btnPanelWid
  132.                  && y > node.pos.y + node.height - halfBtnHgt 
  133.                  && y < node.pos.y + node.height + halfBtnHgt)
  134.                 {
  135.                     // User clicked somewhere on the node button panel
  136.                     // So return button clicked on and the TreeNode's index
  137.                     if (node.hidBtnWid > 0 && x < node.btnPanelX + node.hidBtnWid)
  138.                     {
  139.                         return new Point(BTN_CHANGE_TREE, i);
  140.                     }
  141.                     else
  142.                     {
  143.                         return new Point(BTN_SHOW_IMAGE, i);
  144.                     }
  145.                 }
  146.                 
  147.                 // User did not click on node button panel
  148.                 // So check if user clicked on the node itself
  149.                 if (y < node.pos.y + node.height)
  150.                 {
  151.                     // User clicked on the node - So return info
  152.                     return new Point(BTN_OPEN_PAGE, i);
  153.                 }
  154.             }
  155.         }
  156.     }
  157.     
  158.     // ----------------------------------------------------
  159.     // The user did NOT click on ANY node or node button
  160.     return new Point(BTN_NONE, 0);
  161. }
  162.  
  163. // ******************************************************************
  164. // *****                                                        *****
  165. // *****    FUNCTIONS THAT SET TREE-VIEW QUICK-VIEW POINTERS    *****
  166. // *****   --------------------------------------------------   *****
  167. // *****   Including expanding/contracting Tab root sub-tree's  *****
  168. // *****                                                        *****
  169. // ******************************************************************
  170.  
  171. // ==========================================================
  172. // Restores all TreeNode pointers to their starting values
  173. // ==========================================================
  174. function restoreInitialTreePointers()
  175. {
  176.     for (var i = 0; i < gTreeNodes.length; i++)
  177.     {
  178.         // Restore this TreeNode's pointers
  179.         tNode = gTreeNodes[i];
  180.         tNode.parent = tNode.parentBak;
  181.         tNode.child = tNode.childBak;
  182.         tNode.sibling = tNode.siblingBak;
  183.  
  184.         // Mark this TreeNode and its sub-tree as visible
  185.         tNode.hidden = false;
  186.         tNode.hiddenTreeSize = 0;
  187.         tNode.childCopy = null;
  188.     }
  189. }
  190.  
  191. // ========================================================
  192. // Sets TreeNode pointers for "Show open tabs" quick-view 
  193. // ========================================================
  194. function setTreePointersFor_OpenTabsQuickView()
  195. {
  196.     var tabRoot, tabSibling;
  197.     var numTabNodes = 0;
  198.     
  199.     // ---------------------------------------------
  200.     // Restore initial tree state
  201.     restoreInitialTreePointers();
  202.  
  203.     // Set req TreeNode props for all Tab root sub-tree's
  204.     for (var i = 0; i < gTabRoots.length; i++)
  205.     {
  206.         // Get Tab root TreeNode object
  207.         tabRoot = gTabRoots[i];
  208.  
  209.         // Cut off Tab root sibling if sibling is a closed Tab
  210.         if (tabRoot.sibling !== null)
  211.         {
  212.             tabSibling = tabRoot.sibling;
  213.             if (!tabSibling.inOpenTab)
  214.                 tabRoot.sibling = null;
  215.         }
  216.  
  217.         // Process this Tab's sub-tree
  218.         if (!tabRoot.inOpenTab)
  219.         {
  220.             // This Tab is closed - So hide it completely
  221.             numTabNodes = markSubTreeAsHiddenOrVisible(tabRoot, true);
  222.         }
  223.         else 
  224.         {
  225.             if (tabRoot.child === null)
  226.             {
  227.                 // This open Tab has only one open page
  228.                 numTabNodes = 1;
  229.             }
  230.             else
  231.             {
  232.                 // Get number of TreeNode's for this Tab (its already visible)
  233.                 numTabNodes = markSubTreeAsHiddenOrVisible(tabRoot, false);
  234.             }
  235.         }
  236.  
  237.         // Set number of TreeNode's for this Tab
  238.         tabRoot.tabTreeSize = numTabNodes;
  239.     }
  240. }
  241.  
  242. // =========================================================
  243. // Sets TreeNode pointers for "Show open pages" quick-view 
  244. // =========================================================
  245. function setTreePointersFor_OpenPagesQuickView()
  246. {
  247.     var tabRoot, tabSibling;
  248.     var chainParent, tNode, tSibling;
  249.     var numTabNodes;
  250.     var tabID;
  251.     
  252.     // ---------------------------------------------
  253.     // Restore initial tree state
  254.     restoreInitialTreePointers();
  255.  
  256.     // Cut off closed Tab siblings and hide all Tab sub-tree's
  257.     for (var i = 0; i < gTabRoots.length; i++)
  258.     {
  259.         // Get Tab root TreeNode object
  260.         tabRoot = gTabRoots[i];
  261.  
  262.         // Cut off Tab root sibling for closed Tabs
  263.         if (tabRoot.sibling !== null)
  264.         {
  265.             tabSibling = tabRoot.sibling;
  266.             if (!tabSibling.inOpenTab)
  267.                 tabRoot.sibling = null;
  268.         }
  269.  
  270.         // Hide the Tab sub-tree completely
  271.         markSubTreeAsHiddenOrVisible(tabRoot, true);
  272.     }
  273.     
  274.     // ---------------------------------------------
  275.     // Set open-page chain pointers for all Tabs
  276.     for (var i = 0; i < gTabRoots.length; i++)
  277.     {
  278.         // Get Tab root TreeNode object
  279.         tabRoot = gTabRoots[i];
  280.         
  281.         // Only process Tabs currently open in FF
  282.         if (tabRoot.inOpenTab)
  283.         {
  284.             // Start the open-page chain for this Tab
  285.             tabRoot.hidden = false;
  286.             chainParent = tabRoot;
  287.             tabID = chainParent.histNode.tab;
  288.             numTabNodes = 1;
  289.  
  290.             // Set all open-page chain pointers for this Tab
  291.             for (var ndx = 1; ndx < gTreeNodes.length; ndx++)
  292.             {
  293.                 // Get Tab sub-tree TreeNode
  294.                 tNode = gTreeNodes[ndx];
  295.  
  296.                 // Only process non-Tab-root TreeNode's for this Tab
  297.                 if (tNode.histNode.tab === tabID && tNode !== tabRoot)
  298.                 {
  299.                     // Nullify sibling (only Tab level siblings are shown)
  300.                     tNode.sibling = null;
  301.  
  302.                     // Add to open-page chain if TreeNode is in that chain
  303.                     if (tNode.isOpenPage)
  304.                     {
  305.                         // Increment Tab TreeNode count
  306.                         numTabNodes ++;
  307.  
  308.                         // Set chain pointers and make tNode visible
  309.                         chainParent.child = tNode;
  310.                         tNode.parent = chainParent;
  311.                         tNode.hidden = false;                    
  312.  
  313.                         // Set this TreeNode as the next chain parent
  314.                         chainParent = tNode;
  315.                     }
  316.                 }
  317.             }
  318.  
  319.             // Set number of TreeNode's for this Tab
  320.             tabRoot.tabTreeSize = numTabNodes;
  321.         }
  322.     }
  323. }
  324.  
  325. // ===========================================================
  326. // Sets TreeNode pointers for "Show selected tab" quick-view 
  327. // ===========================================================
  328. function setTreePointersFor_SelectedTabQuickView(tabID)
  329. {
  330.     var tabRoot, treeRoot;
  331.     var numTabNodes;
  332.     
  333.     // ---------------------------------------------
  334.     // Restore initial tree state
  335.     restoreInitialTreePointers();
  336.  
  337.     // Set req TreeNode props for all Tab root sub-tree's
  338.     for (var i = 0; i < gTabRoots.length; i++)
  339.     {
  340.         // Get Tab root TreeNode object
  341.         tabRoot = gTabRoots[i];
  342.  
  343.         // Cut off ALL Tab root siblings
  344.         tabRoot.sibling = null;
  345.  
  346.         // Set Tab sub-tree props
  347.         if (tabRoot.histNode.tab === tabID)
  348.         {
  349.             // Make Tab root with req tabID the only child
  350.             treeRoot = gTreeNodes[0];
  351.             treeRoot.child = tabRoot;
  352.  
  353.             // Get number of TreeNode's for this Tab (its already visible)
  354.             numTabNodes = markSubTreeAsHiddenOrVisible(tabRoot, false);
  355.         }
  356.         else
  357.         {
  358.             // Hide other Tabs completely
  359.             numTabNodes = markSubTreeAsHiddenOrVisible(tabRoot, true);
  360.         }
  361.  
  362.         // Set number of TreeNode's for this Tab
  363.         tabRoot.tabTreeSize = numTabNodes;
  364.     }
  365. }
  366.  
  367. // ==========================================================
  368. // Sets TreeNode pointers for "Show closed tabs" quick-view 
  369. // ==========================================================
  370. function setTreePointersFor_ClosedTabsQuickView()
  371. {
  372.     var treeRoot, tabRoot, tabSibling;
  373.     var firstClosedTab = null;
  374.     var numTabNodes;
  375.  
  376.     // -------------------------------------------------
  377.     // Restore initial tree state
  378.     restoreInitialTreePointers();
  379.     
  380.     // Make treeRoot have no children (may be no closed Tabs)
  381.     treeRoot = gTreeNodes[0];
  382.     treeRoot.child = null;
  383.  
  384.     // --------------------------------------------------
  385.     // Set req TreeNode props for all Tab root sub-tree's
  386.     for (var i = 0; i < gTabRoots.length; i++)
  387.     {
  388.         // Get Tab root TreeNode object
  389.         tabRoot = gTabRoots[i];
  390.  
  391.         // Cut off Tab root sibling for open Tabs
  392.         if (tabRoot.sibling !== null)
  393.         {
  394.             tabSibling = tabRoot.sibling;
  395.             if (tabSibling.inOpenTab)
  396.                 tabRoot.sibling = null;
  397.         }
  398.         
  399.         // Make the treeRoot point to the first closed Tab
  400.         if (!tabRoot.inOpenTab && firstClosedTab === null)
  401.         {
  402.             firstClosedTab = tabRoot;
  403.             treeRoot.child = firstClosedTab;
  404.         }
  405.  
  406.         // Process this Tab's sub-tree
  407.         if (tabRoot.inOpenTab)
  408.         {
  409.             // Hide this open Tab completely
  410.             numTabNodes = markSubTreeAsHiddenOrVisible(tabRoot, true);
  411.         }
  412.         else
  413.         {
  414.             if (tabRoot.child === null)
  415.             {
  416.                 // This closed Tab has only one closed page
  417.                 numTabNodes = 1;
  418.             }
  419.             else
  420.             {
  421.                 // Get number of TreeNode's for this Tab (its already visible)
  422.                 numTabNodes = markSubTreeAsHiddenOrVisible(tabRoot, false);
  423.             }
  424.         }
  425.         
  426.         // Set number of TreeNode's for this Tab
  427.         tabRoot.tabTreeSize = numTabNodes;
  428.     }
  429. }
  430.  
  431. // =============================================================
  432. // Shows or hides sub-tree below root TreeNode user clicked on
  433. // Called from respondToTreeViewMouseClickOnCanvas(x, y)
  434. // =============================================================
  435. function showOrHideSubTreeForRoot(node)
  436. {
  437.     if (node.childCopy === null && node.child !== null)
  438.     {
  439.         // Hide sub-tree
  440.         hideSubTreeForRoot(node);
  441.  
  442.         // Show tree with sub-tree hidden
  443.         drawTree(false, null, null);
  444.     }
  445.     else if (node.childCopy !== null)
  446.     {
  447.         // Make hidden sub-tree visible
  448.         //alert("showing");
  449.         node.hiddenTreeSize = 0;
  450.         node.child = node.childCopy;
  451.         node.childCopy = null;
  452.         markSubTreeAsHiddenOrVisible(node, false);
  453.  
  454.         // Show tree with sub-tree made visible
  455.         drawTree(false, null, null);
  456.     }
  457. }
  458.  
  459. // =========================================================
  460. // Hides the sub-tree that has the passed node as its root
  461. // =========================================================
  462. function hideSubTreeForRoot(node)
  463. {
  464.     // Hide sub-tree
  465.     var subTreeSize = markSubTreeAsHiddenOrVisible(node, true);
  466.     node.hidden = false;
  467.     node.hiddenTreeSize = subTreeSize;
  468.     node.childCopy = node.child;
  469.     node.child = null;
  470. }